﻿namespace KinonekoSoftware.Foundation.UI.ViewModels
{
    partial class ViewModelBase : IViewService, IDialogService
    {
        #region IViewService

        public bool CanGoBack() => Ioc.Get<IViewService>().CanGoBack();

        public bool CanGoForward() => Ioc.Get<IViewService>().CanGoForward();

        public void GoBack() => Ioc.Get<IViewService>().GoBack();

        public void GoForward() => Ioc.Get<IViewService>().GoForward();

        public void GoTo(IPageRoot vm)
        {
            var self = this;
            
            //
            //
            if (self is TabbedShell shell)
            {
                ((IViewService)shell).GoTo(vm);
            }
            else
            {
                
                //
                //
                Ioc.Get<IViewService>().GoTo(vm);
            }
        }

        public void GoTo(IPageRoot vm, IPageContext context)
        {
            var self = this;
            //
            //
            if (self is TabbedShell shell)
            {
                
                ((IViewService)shell).GoTo(vm, (PageContext)context);
            }
            else
            {
                
                //
                //
                Ioc.Get<IViewService>().GoTo(vm, context);
            }
        }

        public void GoTo<T>() where T : ViewModelBase, IPageRoot
        {
            var self = this;
            
            //
            //
            if (self is TabbedShell shell)
            {
                
                shell.GoTo<T>();
            }
            else
            {
                
                //
                //
                Ioc.Get<IViewService>().GoTo(ClassStatic.CreateInstance<T>());
            }
        }

        public void GoTo<T>(IPageContext context) where T : ViewModelBase,IPageRoot
        {
            //
            //
            var self = this;
            var vm   = ClassStatic.CreateInstance<T>();
            
            //
            //
            if (self is TabbedShell shell)
            {
                
                ((IViewService)shell).GoTo(vm, (PageContext)context);
            }
            else
            {
                
                //
                //
                Ioc.Get<IViewService>().GoTo(vm, (PageContext)context);
            }
        }

        public Task Close(IPageRoot vm) => Ioc.Get<IViewService>().Close(vm);

        #endregion

        #region IDialogService

        Task<Result<T>> IDialogService.Dialog<T>(IObjectDialog<T> viewModel) => Dialog<T>(viewModel);

        Task<Result<T>> IDialogService.Dialog<T>(IObjectDialog<T> viewModel, IDialogContext context) => Dialog<T>(viewModel, context);

        Task<Result<IList<T>>> IDialogService.Dialog<T>(ISelectionDialog<T> viewModel) where T : class => Dialog<T>(viewModel);

        Task<Result<IList<T>>> IDialogService.Dialog<T>(ISelectionDialog<T> viewModel, IDialogContext context) where T : class => Dialog<T>(viewModel, context);

        Task<Result<T>> IDialogService.Dialog<T>(IAsyncObjectDialog<T> viewModel) => Dialog<T>(viewModel);

        Task<Result<T>> IDialogService.Dialog<T>(IAsyncObjectDialog<T> viewModel, IDialogContext context) => Dialog<T>(viewModel, context);

        Task<bool> IDialogService.Question(IBooleanDialog viewModel) => Question(viewModel);

        Task<bool> IDialogService.Question(IBooleanDialog viewModel, IDialogContext context) => Question(viewModel, context);

        Task<TripleSelection> IDialogService.Question(string description, string option1Text, string option2Text) => Question(description, option1Text, option2Text);

        Task IDialogService.Notify(INotifyDialog viewModel) => Notify(viewModel);

        Task IDialogService.Notify(INotifyDialog viewModel, IDialogContext context) => Notify(viewModel, context);

        Task<bool> IDialogService.DangerOperation(string title, string description, int count) => DangerOperation(title, description, count);

        Task<bool> IDialogService.SuccessOperation(string title, string description, int count) => SuccessOperation(title, description, count);

        Task<bool> IDialogService.InfoOperation(string title, string description, int count) => InfoOperation(title, description, count);

        Task<bool> IDialogService.WarningOperation(string title, string description, int count) => WarningOperation(title, description, count);

        Task<bool> IDialogService.ObsoletedOperation(string title, string description, int count) => ObsoletedOperation(title, description, count);

        Task IDialogService.Danger(string title, string description, int count) => Danger(title, description, count);

        Task IDialogService.Success(string title, string description, int count) => Success(title, description, count);

        Task IDialogService.Info(string title, string description, int count) => Info(title, description, count);

        Task IDialogService.Warning(string title, string description, int count) => Warning(title, description, count);

        Task IDialogService.Obsoleted(string title, string description, int count) => Obsoleted(title, description, count);

        #endregion

        public static Task<Result<T>> Dialog<T, TViewModel>() where TViewModel : ObjectDialog<T>
        {
            return (Ioc.Get<IDialogService>() as DialogService)?.Dialog<T, TViewModel>();
        }

        public static Task<Result<T>> Dialog<T, TViewModel>(IDialogContext context) where TViewModel : ObjectDialog<T>
        {
            return (Ioc.Get<IDialogService>() as DialogService)?.Dialog<T, TViewModel>((DialogContext)context);
        }

        public static Task<Result<T>> Dialog<T>(IObjectDialog<T> viewModel)
        {
            return Ioc.Get<IDialogService>().Dialog<T>(viewModel);
        }

        public static Task<Result<T>> Dialog<T>(IObjectDialog<T> viewModel, IDialogContext context)
        {
            return Ioc.Get<IDialogService>().Dialog<T>(viewModel, context);
        }

        public static Task<Result<IList<T>>> Dialog<T>(ISelectionDialog<T> viewModel) where T : class
        {
            return Ioc.Get<IDialogService>().Dialog<T>(viewModel);
        }

        public static Task<Result<IList<T>>> Dialog<T>(ISelectionDialog<T> viewModel, IDialogContext context) where T : class
        {
            return Ioc.Get<IDialogService>().Dialog<T>(viewModel, context);
        }

        public static Task<Result<T>> Dialog<T>(IAsyncObjectDialog<T> viewModel)
        {
            return Ioc.Get<IDialogService>().Dialog<T>(viewModel);
        }

        public static Task<Result<T>> Dialog<T>(IAsyncObjectDialog<T> viewModel, IDialogContext context)
        {
            return Ioc.Get<IDialogService>().Dialog<T>(viewModel, context);
        }

        public static Task<bool> Question<T>() where T : BooleanDialog
        {
            return (Ioc.Get<IDialogService>() as DialogService)?.Question<T>();
        }

        public static Task<bool> Question<T>(IDialogContext context) where T : BooleanDialog
        {
            return (Ioc.Get<IDialogService>() as DialogService)?.Question<T>((DialogContext)context);
        }

        public static Task<bool> Question(IBooleanDialog viewModel)
        {
            return Ioc.Get<IDialogService>().Question(viewModel);
        }

        public static Task<bool> Question(IBooleanDialog viewModel, IDialogContext context)
        {
            return Ioc.Get<IDialogService>().Question(viewModel, context);
        }

        public static Task<TripleSelection> Question(string description, string option1Text, string option2Text)
        {
            return Ioc.Get<IDialogService>().Question(description, option1Text, option2Text);
        }

        public static Task Notify(INotifyDialog viewModel)
        {
            return Ioc.Get<IDialogService>().Notify(viewModel);
        }

        public static Task Notify(INotifyDialog viewModel, IDialogContext context)
        {
            return Ioc.Get<IDialogService>().Notify(viewModel, context);
        }

        public static Task<bool> DangerOperation(string title, string description, int count = 0)
        {
            return Ioc.Get<IDialogService>().DangerOperation(title, description, count);
        }

        public static Task<bool> SuccessOperation(string title, string description, int count = 0)
        {
            return Ioc.Get<IDialogService>().SuccessOperation(title, description, count);
        }

        public static Task<bool> InfoOperation(string title, string description, int count = 0)
        {
            return Ioc.Get<IDialogService>().InfoOperation(title, description, count);
        }

        public static Task<bool> WarningOperation(string title, string description, int count = 0)
        {
            return Ioc.Get<IDialogService>().WarningOperation(title, description, count);
        }

        public static Task<bool> ObsoletedOperation(string title, string description, int count = 0)
        {
            return Ioc.Get<IDialogService>().ObsoletedOperation(title, description, count);
        }

        public static Task Danger(string title, string description, int count = 0)
        {
            return Ioc.Get<IDialogService>().Danger(title, description, count);
        }

        public static Task Success(string title, string description, int count = 0)
        {
            return Ioc.Get<IDialogService>().Success(title, description, count);
        }

        public static Task Info(string title, string description, int count = 0)
        {
            return Ioc.Get<IDialogService>().Info(title, description, count);
        }

        public static Task Warning(string title, string description, int count = 0)
        {
            return Ioc.Get<IDialogService>().Warning(title, description, count);
        }

        public static Task Obsoleted(string title, string description, int count = 0)
        {
            return Ioc.Get<IDialogService>().Obsoleted(title, description, count);
        }


        public static Task<bool> RemoveItem(string title = null, string description = null)
        {
            if (string.IsNullOrEmpty(title))
            {
                title = LanguageManager.GetText("Title.Deleting");
            }
            if (string.IsNullOrEmpty(description))
            {
                description = LanguageManager.GetText("Text.Remove.Item");
            }

            return DangerOperation(title, description);
        }


        public static Task<Result<string>> SingleText(string title, string description, string value = null, int limit = 200)
        {
            var ds      = Ioc.Get<IDialogService>();
            var vm      = new SingleLineViewModel();
            var context = new DialogContext();

            context.Set(DialogContext.Key_Limit, limit);
            context.Set(ContextBase.Key_Value, value);

            vm.Title       = title;
            vm.Description = description;

            return ds.Dialog<string>(vm, context);
        }
        
        public static Task<Result<string>> MultiText(string title, string description, string value = null, int limit = 200)
        {
            var ds      = Ioc.Get<IDialogService>();
            var vm      = new MultiLineViewModel();
            var context = new DialogContext();

            context.Set(DialogContext.Key_Limit, limit);
            context.Set(ContextBase.Key_Value, value);

            vm.Title       = title;
            vm.Description = description;

            return ds.Dialog<string>(vm, context);
        }
    }
}